package com.koron.device.utils;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;

/**
 * @author twcao
 * @title: ForkJoinTask
 * @description: 数据批量入库， 既保证sql长度不会超过最大值，也可以多线程入库，保证速度
 * @date 2021/8/3018:08
 */
@Slf4j
public class ForkJoinTask<T> extends RecursiveTask<Integer>  {

    private int start;
    private int end;
    private List<T> list;
    //临界值
    private static final int THRESHOLD = 5000;
    // 可以调用方法method的实体
    private Object obj;
    // obj中要执行的方法
    private Method method;

    public ForkJoinTask(int start, int end, List<T> list, Object obj, String methodName) {
        this.start = start;
        this.end = end;
        this.list = list;
        this.obj = obj;
        try {
            method = obj.getClass().getDeclaredMethod(methodName, List.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    protected Integer compute() {
        int length = end -start;
        if (length <= THRESHOLD){
            List<T> temList = new ArrayList<>();
            for (int i = start; i < end;i++) {
                temList.add(list.get(i));
            }
            try {
                return (Integer) method.invoke(this.obj, temList);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return 0;
            }
        }else {
            int middle = (start + end)/2;
            ForkJoinTask left = new ForkJoinTask(start, middle, list, obj, method.getName());
            left.fork();
            ForkJoinTask right = new ForkJoinTask(middle + 1, end ,list, obj, method.getName());
            right.fork();
            int l = (Integer) left.join() + (Integer)right.join();
            return l;
        }
    }
}
